﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
using TjZheng.Framework;

namespace TjZheng.JiaLi.Process
{
    public sealed class TicketInfo
    {
        public string Version { get; set; }
        public string BindAccount { get; set; }
        public string CpuIdentity { get; set; }
        public DateTime CreateTime { get; set; }
        public DateTime? ExpireTime { get; set; }

        public static string EncryptKey
        {
            get
            {
                return "jqmhtjtz";
            }
        }

        public static string TicketPath
        {
            get
            {
                return AppDomain.CurrentDomain.BaseDirectory + "Active.xml";
            }
        }

        public static string RunVersion
        {
            get
            {
                return ConfigHelper.GetValue("RunVersion");
            }
        }

        public static InvokeResult CheckActivatedTicket()
        {
            InvokeResult objInvokeResult = new InvokeResult();
            XmlDocument objXmlDocument = TicketPath.CreateXmlDocument();
            if (objXmlDocument == null)
            {
                objInvokeResult.ResultCode = "ActiveNull";
                objInvokeResult.ResultMessage = "对不起，您的激活文件丢失";
                return objInvokeResult;
            }
            XmlNode objXmlNode = objXmlDocument.DocumentElement.SelectSingleNode("//Active/Input");
            if (objXmlNode == null)
            {
                objInvokeResult.ResultCode = "InputXmlNull";
                objInvokeResult.ResultMessage = "对不起，您的Input激活码丢失";
                return objInvokeResult;
            }
            string inputTicket = objXmlNode.InnerText;
            if (inputTicket.IsNull())
            {
                objInvokeResult.ResultCode = "InputNull";
                objInvokeResult.ResultMessage = "对不起，您的Input激活码不存在";
                return objInvokeResult;
            }
            objXmlNode = objXmlDocument.DocumentElement.SelectSingleNode("//Active/Valid");
            if (objXmlNode == null)
            {
                objInvokeResult.ResultCode = "InputXmlNull";
                objInvokeResult.ResultMessage = "对不起，您的Input激活码丢失";
                return objInvokeResult;
            }
            string validTicket = objXmlNode.InnerText;
            if (validTicket.IsNull())
            {
                objInvokeResult.ResultCode = "ValidNull";
                objInvokeResult.ResultMessage = "对不起，您的Valid激活码丢失";
                return objInvokeResult;
            }
            objInvokeResult = CheckActivatedTicket(inputTicket, validTicket);
            return objInvokeResult;
        }
        public static InvokeResult CheckActivatedTicket(string inputTicket, string validTicket)
        {
            InvokeResult objInvokeResult = new InvokeResult();
            if (inputTicket.IsNull())
            {
                objInvokeResult.ResultCode = "InputNull";
                objInvokeResult.ResultMessage = "对不起，您的Input激活码不存在";
                return objInvokeResult;
            }
            if (validTicket.IsNull())
            {
                objInvokeResult.ResultCode = "ValidNull";
                objInvokeResult.ResultMessage = "对不起，您的Valid激活码丢失";
                return objInvokeResult;
            }
            try
            {
                inputTicket = inputTicket.DecryptDES("jqmhtjtz");
                validTicket = validTicket.DecryptDES("jqmhtjtz");
                TicketInfo objTicketInfo1 = inputTicket.JsonDeserialize<TicketInfo>();
                TicketInfo objTicketInfo2 = validTicket.JsonDeserialize<TicketInfo>();
                if (objTicketInfo1.Version != objTicketInfo2.Version || objTicketInfo1.Version != RunVersion)
                {
                    objInvokeResult.ResultCode = "VersionNotMatch";
                    objInvokeResult.ResultMessage = "对不起，激活码不适用于本版本";
                    return objInvokeResult;
                }
                if (objTicketInfo1.BindAccount != objTicketInfo2.BindAccount)
                {
                    objInvokeResult.ResultCode = "BindAccountNotMatch";
                    objInvokeResult.ResultMessage = "对不起，激活帐号不匹配";
                    return objInvokeResult;
                }
                string cpuIdentity = MachineHelper.GetCpuIdentity();
                if (objTicketInfo1.CpuIdentity != cpuIdentity || objTicketInfo2.CpuIdentity != cpuIdentity)
                {
                    objInvokeResult.ResultCode = "MachineNotMatch";
                    objInvokeResult.ResultMessage = "对不起，您的机器信息不匹配";
                    return objInvokeResult;
                }
                if (objTicketInfo1.CreateTime.ToString("yyyy-MM-dd HH:mm:ss") != objTicketInfo2.CreateTime.ToString("yyyy-MM-dd HH:mm:ss"))
                {
                    objInvokeResult.ResultCode = "CreateTimeNotMatch";
                    objInvokeResult.ResultMessage = "对不起，激活码的时间与机器码不匹配";
                    return objInvokeResult;
                }
                if (objTicketInfo2.ExpireTime.HasValue)
                {
                    if (!DateTime.Now.AddHours(-8).IsInTime(objTicketInfo2.CreateTime, objTicketInfo2.ExpireTime.Value))
                    {
                        objInvokeResult.ResultCode = "TicketExpired";
                        objInvokeResult.ResultMessage = "对不起，您的产品已过期，请您与管理员联系";
                        return objInvokeResult;

                    }
                }
            }
            catch (Exception)
            {
                objInvokeResult.ResultCode = "SerializeError";
                objInvokeResult.ResultMessage = "对不起，错误的激活码";
                return objInvokeResult;
            }
            return objInvokeResult;
        }
        public static InvokeResult CheckTrialTicket()
        {
            InvokeResult objInvokeResult = new InvokeResult();
            XmlDocument objXmlDocument = TicketPath.CreateXmlDocument();
            if (objXmlDocument == null)
            {
                objInvokeResult.ResultCode = "ActiveNull";
                objInvokeResult.ResultMessage = "对不起，您的试用文件丢失";
                return objInvokeResult;
            }
            XmlNode objXmlNode = objXmlDocument.DocumentElement.SelectSingleNode("//Trial/Input");
            if (objXmlNode == null)
            {
                objInvokeResult.ResultCode = "InputXmlNull";
                objInvokeResult.ResultMessage = "对不起，您的Input试用码丢失";
                return objInvokeResult;
            }
            string inputTicket = objXmlNode.InnerText;
            objXmlNode = objXmlDocument.DocumentElement.SelectSingleNode("//Trial/Valid");
            string validTicket = objXmlNode.InnerText;
            if (validTicket.IsNull())
            {
                objInvokeResult.ResultCode = "ValidNull";
                objInvokeResult.ResultMessage = "对不起，您的Valid试用码丢失";
                return objInvokeResult;
            }
            return objInvokeResult = CheckTrialTicket(inputTicket, validTicket);
        }
        public static InvokeResult CheckTrialTicket(string inputTicket, string validTicket)
        {
            InvokeResult objInvokeResult = new InvokeResult();
            if (inputTicket.IsNull())
            {
                objInvokeResult.ResultCode = "InputNull";
                objInvokeResult.ResultMessage = "对不起，您的Input试用码不存在";
                return objInvokeResult;
            }
            if (validTicket.IsNull())
            {
                objInvokeResult.ResultCode = "ValidNull";
                objInvokeResult.ResultMessage = "对不起，您的Valid试用码丢失";
                return objInvokeResult;
            }
            try
            {
                inputTicket = inputTicket.DecryptDES("jqmhtjtz");
                validTicket = validTicket.DecryptDES("jqmhtjtz");
                TicketInfo objTicketInfo1 = inputTicket.JsonDeserialize<TicketInfo>();
                TicketInfo objTicketInfo2 = validTicket.JsonDeserialize<TicketInfo>();
                if (objTicketInfo1.Version != objTicketInfo2.Version || objTicketInfo1.Version != RunVersion)
                {
                    objInvokeResult.ResultCode = "VersionNotMatch";
                    objInvokeResult.ResultMessage = "对不起，试用码不适用于本版本";
                    return objInvokeResult;
                }
                string cpuIdentity = MachineHelper.GetCpuIdentity();
                if (objTicketInfo1.CpuIdentity != cpuIdentity || objTicketInfo2.CpuIdentity != cpuIdentity)
                {
                    objInvokeResult.ResultCode = "MachineNotMatch";
                    objInvokeResult.ResultMessage = "对不起，您的机器信息不匹配";
                    return objInvokeResult;
                }
                if (objTicketInfo1.CreateTime != objTicketInfo2.CreateTime)
                {
                    objInvokeResult.ResultCode = "CreateTimeNotMatch";
                    objInvokeResult.ResultMessage = "对不起，激活码的时间与机器码不匹配";
                    return objInvokeResult;
                }
                if (objTicketInfo2.ExpireTime.HasValue)
                {
                    if (!DateTime.Now.AddHours(-8).IsInTime(objTicketInfo2.CreateTime, objTicketInfo2.ExpireTime.Value))
                    {
                        objInvokeResult.ResultCode = "TicketExpired";
                        objInvokeResult.ResultMessage = "对不起，您的产品已过期，请您与管理员联系";
                        return objInvokeResult;
                    }
                }
            }
            catch (Exception)
            {
                objInvokeResult.ResultCode = "SerializeError";
                objInvokeResult.ResultMessage = "对不起，错误的试用码";
                return objInvokeResult;
            }
            return objInvokeResult;
        }

        public static InvokeResult CheckTicket()
        {
            InvokeResult objInvokeResult = CheckIsActive();
            if (objInvokeResult.ResultCode != "Success")
            {
                return objInvokeResult;
            }
            if (Convert.ToString(objInvokeResult.Data).ToLower() == "true")
            {
                return objInvokeResult = CheckActivatedTicket();
            }
            return objInvokeResult = CheckTrialTicket();
        }

        public static InvokeResult CheckIsActive()
        {
            InvokeResult objInvokeResult = new InvokeResult();
            XmlDocument objXmlDocument = TicketPath.CreateXmlDocument();
            if (objXmlDocument == null)
            {
                objInvokeResult.ResultCode = "ActiveNull";
                objInvokeResult.ResultMessage = "对不起，您的激活文件丢失";
                return objInvokeResult;
            }
            XmlNode objXmlNode = objXmlDocument.DocumentElement.SelectSingleNode("//IsActive");
            if (objXmlNode == null)
            {
                objInvokeResult.ResultCode = "IsActiveXmlNull";
                objInvokeResult.ResultMessage = "对不起，激活节点丢失";
                return objInvokeResult;
            }
            if (objXmlNode.InnerText.IsNull())
            {
                objInvokeResult.ResultCode = "IsActiveNull";
                objInvokeResult.ResultMessage = "对不起，激活节点为空";
                return objInvokeResult;
            }
            string isActive = objXmlNode.InnerText.Trim().ToLower();
            List<string> objList = new List<string> { "true", "false" };
            if (!objList.Contains(isActive))
            {
                objInvokeResult.ResultCode = "IsActiveError";
                objInvokeResult.ResultMessage = "对不起，请不要篡改激活节点";
                return objInvokeResult;
            }
            objInvokeResult.Data = isActive;
            return objInvokeResult;
        }

        public static TicketInfo GetTicketInfo(string TicketType = "Valid")
        {
            TicketInfo objTicketInfo = null;
            InvokeResult objInvokeResult = CheckIsActive();
            if (objInvokeResult.ResultCode != "Success")
            {
                return objTicketInfo;
            }
            XmlDocument objXmlDocument = TicketPath.CreateXmlDocument();
            if (objXmlDocument == null)
            {
                return objTicketInfo;
            }
            bool isActive = Convert.ToString(objInvokeResult.Data).ToLower() == "true";
            XmlNode objXmlNode = objXmlDocument.DocumentElement.SelectSingleNode(string.Format("//{0}/{1}", isActive ? "Active" : "Trial", TicketType));
            if (objXmlNode == null)
            {
                return objTicketInfo;
            }
            string validTicket = objXmlNode.InnerText;
            if (validTicket.IsNull())
            {
                return objTicketInfo;
            }
            try
            {
                objTicketInfo = validTicket.DecryptDES("jqmhtjtz").JsonDeserialize<TicketInfo>();
            }
            catch (Exception)
            {
            }
            return objTicketInfo;
        }

        public static string CreateInputTicket(string bindAccount)
        {
            TicketInfo objTicketInfo = new TicketInfo();
            objTicketInfo.Version = RunVersion;
            objTicketInfo.BindAccount = bindAccount;
            objTicketInfo.CpuIdentity = MachineHelper.GetCpuIdentity();
            objTicketInfo.CreateTime = DateTime.Now;
            return objTicketInfo.JsonSerialize().EncryptDES("jqmhtjtz");
        }

        public static string CreateValidTicket(string inputTicket, TimeSpan? expireTime)
        {
            if (inputTicket.IsNull())
            {
                return inputTicket;
            }
            TicketInfo objTicketInfo1 = inputTicket.DecryptDES("jqmhtjtz").JsonDeserialize<TicketInfo>();
            if (expireTime.HasValue)
            {
                objTicketInfo1.ExpireTime = objTicketInfo1.CreateTime.Add(expireTime.Value);
            }
            return objTicketInfo1.JsonSerialize().EncryptDES("jqmhtjtz");
        }
    }
}
